#ifndef K_PAGE_H
#define K_PAGE_H
#pragma once

#include "KList.h"
#include <cstdint>

class KStorage;

class KPage : public KList::Node, KLockable {
public:
    explicit KPage(size_t pageSize = 0);
public:
    bool atEnd() const              { return !space(); }
    size_t bytesAvailable() const   { return size_t(m_write - m_read); }
    size_t space() const            { return size_t(m_data + size() - m_write); }
    size_t size() const             { return m_size; }
public:
    void clear()                    { m_read = m_write = m_data; }
    void free();
    bool reset();
    size_t ignore(size_t length)    { return read(NULL, length); }
    size_t peek(void *dest, size_t length);
    size_t read(void *dest, size_t length);
    size_t write(const void *src, size_t length);
    size_t write(KStorage *src, size_t length);
protected:
    virtual void *allocMemory() = 0;
    virtual void freeMemory(void *data) = 0;
private:
    typedef uint8_t *BytePtr;
    BytePtr m_data;
    volatile BytePtr m_read, m_write;
    const size_t m_size;
};

#endif // K_PAGE_H